// Copyright 2011 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "google/protobuf-expectation/proto-kit-converter.h"

#include <stddef.h>
#include <string>

#include "glog/logging.h"
#include "google/protobuf-expectation/unittest-kit.pb.h"
#include "google/protobuf-expectation/unittest.pb.h"
#include "google/protobuf-expectation/expectation.pb.h"
#include "google/protobuf-expectation/expectation-eval.h"
#include "google/protobuf/text_format.h"
#include "gtest/gtest.h"

using std::string;

using google::protobuf::TextFormat;

namespace google {
namespace protobuf_expectation {

class ExpectationConverterTest : public ::testing::Test {
 protected:
  bool Convert() {
    VLOG(1) << "from: " << expectation_.DebugString();
    const bool result =
        ConvertToGenericExpectation(TestAllTypes::descriptor(), expectation_,
                                    &generic_expectation_);
    VLOG(1) << "to: " << generic_expectation_.DebugString();
    return result;
  }

  TestAllTypes proto_;
  TestAllTypesKit expectation_;
  MessageExpectation generic_expectation_;
};

TEST_F(ExpectationConverterTest, InvalidFieldValueExpectation) {
  // Empty expectation.
  CHECK(TextFormat::ParseFromString(
      "optional_int32: { }",
      &expectation_));
  EXPECT_FALSE(Convert());
  // Two operators.
  CHECK(TextFormat::ParseFromString(
      "optional_int32: { eq: \"123\" ne: \"123\" }",
      &expectation_));
  EXPECT_FALSE(Convert());
  // One operator and is.
  CHECK(TextFormat::ParseFromString(
      "optional_int32: { eq: \"123\" is: < ne: \"123\" > }",
      &expectation_));
  EXPECT_FALSE(Convert());
  // One operator and is_not.
  CHECK(TextFormat::ParseFromString(
      "optional_int32: { eq: \"123\" is_not: < ne: \"123\" > }",
      &expectation_));
  EXPECT_FALSE(Convert());
  // Is and is_not.
  CHECK(TextFormat::ParseFromString(
      "optional_int32: { is: < eq: \"123\" > is_not: < eq: \"123\" > }",
      &expectation_));
  EXPECT_FALSE(Convert());
  // And without an operator.
  CHECK(TextFormat::ParseFromString(
      "optional_int32: { and: < eq: \"123\" > }",
      &expectation_));
  EXPECT_FALSE(Convert());
  // Or without an operator.
  CHECK(TextFormat::ParseFromString(
      "optional_int32: { or: < eq: \"123\" > }",
      &expectation_));
  EXPECT_FALSE(Convert());
  // And and or.
  CHECK(TextFormat::ParseFromString(
      "optional_int32: {  eq: \"123\" and: < eq: \"123\" > "
      "                               or: < eq: \"123\" > }",
      &expectation_));
  EXPECT_FALSE(Convert());
  // Nested.
  CHECK(TextFormat::ParseFromString(
      "optional_int32: { is: < eq: \"123\" ne: \"123\" > }",
      &expectation_));
  EXPECT_FALSE(Convert());
}

TEST_F(ExpectationConverterTest, OptionalInt32) {
  CHECK(TextFormat::ParseFromString(
      "optional_int32: { eq: \"123\" }",
      &expectation_));
  CHECK(Convert());
  EXPECT_EQ(1, generic_expectation_.field_expectation_size());
  const FieldExpectation& expectation =
      generic_expectation_.field_expectation(0);
  EXPECT_EQ("optional_int32", expectation.field_name());
  EXPECT_EQ(ValueExpectation::EQ, expectation.value_expectation().operator_());
  EXPECT_EQ("123", expectation.value_expectation().value());

  proto_.set_optional_int32(123);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.set_optional_int32(321);
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
}

TEST_F(ExpectationConverterTest, OptionalStringLength) {
  CHECK(TextFormat::ParseFromString(
      "optional_string: { length: { eq: \"3\" } }",
      &expectation_));
  CHECK(Convert());
  EXPECT_EQ(1, generic_expectation_.field_expectation_size());
  const FieldExpectation& expectation =
      generic_expectation_.field_expectation(0);
  EXPECT_EQ("optional_string", expectation.field_name());
  EXPECT_EQ(ValueExpectation::STRING_LENGTH,
            expectation.value_expectation().operator_());
  EXPECT_EQ(1, expectation.value_expectation().value_expectation_size());
  const ValueExpectation& value_expectation =
      expectation.value_expectation().value_expectation(0);
  EXPECT_EQ(ValueExpectation::EQ, value_expectation.operator_());
  EXPECT_EQ("3", value_expectation.value());

  proto_.set_optional_string("fo");
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.set_optional_string("foo");
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.set_optional_string("fooo");
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
}

TEST_F(ExpectationConverterTest, OptionalStringFullMatchRe) {
  CHECK(TextFormat::ParseFromString(
      "optional_string: { full_match_re: \"fo*\" }",
      &expectation_));
  CHECK(Convert());
  EXPECT_EQ(1, generic_expectation_.field_expectation_size());
  const FieldExpectation& expectation =
      generic_expectation_.field_expectation(0);
  EXPECT_EQ("optional_string", expectation.field_name());
  EXPECT_EQ(ValueExpectation::FULL_MATCH_RE,
            expectation.value_expectation().operator_());
  EXPECT_EQ("fo*", expectation.value_expectation().value());

  proto_.set_optional_string("foo");
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.set_optional_string("foot");
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.set_optional_string("bar");
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
}

TEST_F(ExpectationConverterTest, OptionalStringPartialMatchRe) {
  CHECK(TextFormat::ParseFromString(
      "optional_string: { partial_match_re: \"fo*\" }",
      &expectation_));
  CHECK(Convert());
  EXPECT_EQ(1, generic_expectation_.field_expectation_size());
  const FieldExpectation& expectation =
      generic_expectation_.field_expectation(0);
  EXPECT_EQ("optional_string", expectation.field_name());
  EXPECT_EQ(ValueExpectation::PARTIAL_MATCH_RE,
            expectation.value_expectation().operator_());
  EXPECT_EQ("fo*", expectation.value_expectation().value());

  proto_.set_optional_string("foo");
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.set_optional_string("foot");
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.set_optional_string("bar");
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
}

TEST_F(ExpectationConverterTest, Is) {
  CHECK(TextFormat::ParseFromString(
      "optional_int32: { is: { ne: \"123\" } }",
      &expectation_));
  CHECK(Convert());
  EXPECT_EQ(1, generic_expectation_.field_expectation_size());
  const FieldExpectation& expectation =
      generic_expectation_.field_expectation(0);
  EXPECT_EQ("optional_int32", expectation.field_name());
  EXPECT_EQ(ValueExpectation::IS, expectation.value_expectation().operator_());
  EXPECT_EQ(1, expectation.value_expectation().value_expectation_size());
  const ValueExpectation& value_expectation =
      expectation.value_expectation().value_expectation(0);
  EXPECT_EQ(ValueExpectation::NE, value_expectation.operator_());
  EXPECT_EQ("123", value_expectation.value());

  proto_.set_optional_int32(123);
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.set_optional_int32(321);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
}

TEST_F(ExpectationConverterTest, IsNot) {
  CHECK(TextFormat::ParseFromString(
      "optional_int32: { is_not: { eq: \"123\" } }",
      &expectation_));
  CHECK(Convert());
  EXPECT_EQ(1, generic_expectation_.field_expectation_size());
  const FieldExpectation& expectation =
      generic_expectation_.field_expectation(0);
  EXPECT_EQ("optional_int32", expectation.field_name());
  EXPECT_EQ(ValueExpectation::IS_NOT,
            expectation.value_expectation().operator_());
  EXPECT_EQ(1, expectation.value_expectation().value_expectation_size());
  const ValueExpectation& value_expectation =
      expectation.value_expectation().value_expectation(0);
  EXPECT_EQ(ValueExpectation::EQ, value_expectation.operator_());
  EXPECT_EQ("123", value_expectation.value());

  proto_.set_optional_int32(123);
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.set_optional_int32(321);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
}

TEST_F(ExpectationConverterTest, And) {
  CHECK(TextFormat::ParseFromString(
      "optional_int32: { gt: \"1\" and: { lt: \"3\" } }",
      &expectation_));
  CHECK(Convert());
  EXPECT_EQ(1, generic_expectation_.field_expectation_size());
  const FieldExpectation& expectation =
      generic_expectation_.field_expectation(0);
  EXPECT_EQ("optional_int32", expectation.field_name());
  const ValueExpectation& value_expectation = expectation.value_expectation();
  EXPECT_EQ(ValueExpectation::AND, value_expectation.operator_());
  EXPECT_EQ(2, value_expectation.value_expectation_size());
  EXPECT_EQ(ValueExpectation::GT,
            value_expectation.value_expectation(0).operator_());
  EXPECT_EQ("1", value_expectation.value_expectation(0).value());
  EXPECT_EQ(ValueExpectation::LT,
            value_expectation.value_expectation(1).operator_());
  EXPECT_EQ("3", value_expectation.value_expectation(1).value());

  proto_.set_optional_int32(1);
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.set_optional_int32(2);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.set_optional_int32(3);
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
}

TEST_F(ExpectationConverterTest, Or) {
  CHECK(TextFormat::ParseFromString(
      "optional_int32: { le: \"1\" or: { ge: \"3\" } }",
      &expectation_));
  CHECK(Convert());
  EXPECT_EQ(1, generic_expectation_.field_expectation_size());
  const FieldExpectation& expectation =
      generic_expectation_.field_expectation(0);
  EXPECT_EQ("optional_int32", expectation.field_name());
  const ValueExpectation& value_expectation = expectation.value_expectation();
  EXPECT_EQ(ValueExpectation::OR, value_expectation.operator_());
  EXPECT_EQ(2, value_expectation.value_expectation_size());
  EXPECT_EQ(ValueExpectation::LE,
            value_expectation.value_expectation(0).operator_());
  EXPECT_EQ("1", value_expectation.value_expectation(0).value());
  EXPECT_EQ(ValueExpectation::GE,
            value_expectation.value_expectation(1).operator_());
  EXPECT_EQ("3", value_expectation.value_expectation(1).value());

  proto_.set_optional_int32(1);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.set_optional_int32(2);
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.set_optional_int32(3);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
}

TEST_F(ExpectationConverterTest, OptionalMessage) {
  CHECK(TextFormat::ParseFromString(
      "optional_nested_message: { bb: { eq: \"123\" } }",
      &expectation_));
  CHECK(Convert());
  EXPECT_EQ(1, generic_expectation_.field_expectation_size());
  const FieldExpectation& expectation =
      generic_expectation_.field_expectation(0);
  EXPECT_EQ("optional_nested_message", expectation.field_name());
  EXPECT_EQ(1,
            expectation.message_expectation().field_expectation_size());
  const FieldExpectation& bb_expectation =
      expectation.message_expectation().field_expectation(0);
  EXPECT_EQ("bb", bb_expectation.field_name());
  EXPECT_EQ(ValueExpectation::EQ,
            bb_expectation.value_expectation().operator_());
  EXPECT_EQ("123", bb_expectation.value_expectation().value());

  proto_.mutable_optional_nested_message()->set_bb(123);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.mutable_optional_nested_message()->set_bb(321);
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
}

TEST_F(ExpectationConverterTest, RepeatedInt32FieldSize) {
  CHECK(TextFormat::ParseFromString(
      "repeated_int32: { field_size: { eq: \"2\" } }",
      &expectation_));
  CHECK(Convert());
  EXPECT_EQ(1, generic_expectation_.field_expectation_size());
  const FieldExpectation& expectation =
      generic_expectation_.field_expectation(0);
  EXPECT_EQ("repeated_int32", expectation.field_name());
  EXPECT_EQ(ValueExpectation::EQ, expectation.field_size().operator_());
  EXPECT_EQ("2", expectation.field_size().value());

  proto_.add_repeated_int32(1);
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.add_repeated_int32(2);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.add_repeated_int32(3);
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
}

TEST_F(ExpectationConverterTest, RepeatedInt32ForEach) {
  CHECK(TextFormat::ParseFromString(
      "repeated_int32: { for_each: { value: { le: \"2\" } } }",
      &expectation_));
  CHECK(Convert());
  EXPECT_EQ(1, generic_expectation_.field_expectation_size());
  const FieldExpectation& expectation =
      generic_expectation_.field_expectation(0);
  EXPECT_EQ("repeated_int32", expectation.field_name());
  const RepeatedValueExpectation::ForEach& for_each =
      expectation.repeated_value_expectation().for_each();
  EXPECT_EQ(ValueExpectation::LE, for_each.value_expectation().operator_());
  EXPECT_EQ("2", for_each.value_expectation().value());

  proto_.add_repeated_int32(1);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.add_repeated_int32(2);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.add_repeated_int32(3);
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
}

TEST_F(ExpectationConverterTest, RepeatedInt32Have) {
  CHECK(TextFormat::ParseFromString(
      "repeated_int32: { have: { value: { eq: \"2\" } } }",
      &expectation_));
  CHECK(Convert());
  EXPECT_EQ(1, generic_expectation_.field_expectation_size());
  const FieldExpectation& expectation =
      generic_expectation_.field_expectation(0);
  EXPECT_EQ("repeated_int32", expectation.field_name());
  EXPECT_EQ(1, expectation.repeated_value_expectation().have_size());
  const RepeatedValueExpectation::Have& have =
      expectation.repeated_value_expectation().have(0);
  EXPECT_EQ(ValueExpectation::EQ, have.value_expectation().operator_());
  EXPECT_EQ("2", have.value_expectation().value());

  proto_.add_repeated_int32(1);
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.add_repeated_int32(2);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.add_repeated_int32(3);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
}

TEST_F(ExpectationConverterTest, RepeatedInt32HaveAtIndex) {
  CHECK(TextFormat::ParseFromString(
      "repeated_int32: { have: { value: { eq: \"2\" }"
      "                          at_index: { eq: \"1\" } } }",
      &expectation_));
  CHECK(Convert());
  EXPECT_EQ(1, generic_expectation_.field_expectation_size());
  const FieldExpectation& expectation =
      generic_expectation_.field_expectation(0);
  EXPECT_EQ("repeated_int32", expectation.field_name());
  EXPECT_EQ(1, expectation.repeated_value_expectation().have_size());
  const RepeatedValueExpectation::Have& have =
      expectation.repeated_value_expectation().have(0);
  EXPECT_EQ(ValueExpectation::EQ, have.value_expectation().operator_());
  EXPECT_EQ("2", have.value_expectation().value());
  EXPECT_EQ(ValueExpectation::EQ, have.at_index().operator_());
  EXPECT_EQ("1", have.at_index().value());

  proto_.add_repeated_int32(2);
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.add_repeated_int32(2);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.add_repeated_int32(2);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
}

TEST_F(ExpectationConverterTest, RepeatedInt32DoNotHave) {
  CHECK(TextFormat::ParseFromString(
      "repeated_int32: { do_not_have: { value: { eq: \"2\" } } }",
      &expectation_));
  CHECK(Convert());
  EXPECT_EQ(1, generic_expectation_.field_expectation_size());
  const FieldExpectation& expectation =
      generic_expectation_.field_expectation(0);
  EXPECT_EQ("repeated_int32", expectation.field_name());
  EXPECT_EQ(1, expectation.repeated_value_expectation().do_not_have_size());
  const RepeatedValueExpectation::DoNotHave& do_not_have =
      expectation.repeated_value_expectation().do_not_have(0);
  EXPECT_EQ(ValueExpectation::EQ,
            do_not_have.value_expectation().operator_());
  EXPECT_EQ("2", do_not_have.value_expectation().value());

  proto_.add_repeated_int32(1);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.add_repeated_int32(2);
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.add_repeated_int32(3);
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
}

TEST_F(ExpectationConverterTest, RepeatedMessageFieldSize) {
  CHECK(TextFormat::ParseFromString(
      "repeated_nested_message: { field_size: { eq: \"2\" } }",
      &expectation_));
  CHECK(Convert());
  EXPECT_EQ(1, generic_expectation_.field_expectation_size());
  const FieldExpectation& expectation =
      generic_expectation_.field_expectation(0);
  EXPECT_EQ("repeated_nested_message", expectation.field_name());
  EXPECT_TRUE(expectation.has_field_size());
  EXPECT_EQ(ValueExpectation::EQ, expectation.field_size().operator_());
  EXPECT_EQ("2", expectation.field_size().value());

  proto_.add_repeated_nested_message()->set_bb(1);
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.add_repeated_nested_message()->set_bb(2);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.add_repeated_nested_message()->set_bb(3);
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
}

TEST_F(ExpectationConverterTest, RepeatedMessageForEach) {
  CHECK(TextFormat::ParseFromString(
      "repeated_nested_message: { for_each: { bb: { le: \"2\" } } }",
      &expectation_));
  CHECK(Convert());
  EXPECT_EQ(1, generic_expectation_.field_expectation_size());
  const FieldExpectation& expectation =
      generic_expectation_.field_expectation(0);
  EXPECT_EQ("repeated_nested_message", expectation.field_name());
  const RepeatedMessageExpectation::ForEach& for_each =
      expectation.repeated_message_expectation().for_each();
  EXPECT_EQ(1, for_each.message_expectation().field_expectation_size());
  const FieldExpectation& bb_expectation =
      for_each.message_expectation().field_expectation(0);
  EXPECT_EQ("bb", bb_expectation.field_name());
  EXPECT_EQ(ValueExpectation::LE,
            bb_expectation.value_expectation().operator_());
  EXPECT_EQ("2", bb_expectation.value_expectation().value());

  proto_.add_repeated_nested_message()->set_bb(1);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.add_repeated_nested_message()->set_bb(2);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.add_repeated_nested_message()->set_bb(3);
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
}

TEST_F(ExpectationConverterTest, RepeatedMessageHave) {
  CHECK(TextFormat::ParseFromString(
      "repeated_nested_message: { have: { bb: { eq: \"2\" } } }",
      &expectation_));
  CHECK(Convert());
  EXPECT_EQ(1, generic_expectation_.field_expectation_size());
  const FieldExpectation& expectation =
      generic_expectation_.field_expectation(0);
  EXPECT_EQ("repeated_nested_message", expectation.field_name());
  EXPECT_EQ(1, expectation.repeated_message_expectation().have_size());
  const RepeatedMessageExpectation::Have& have =
      expectation.repeated_message_expectation().have(0);
  EXPECT_EQ(1, have.message_expectation().field_expectation_size());
  const FieldExpectation& bb_expectation =
      have.message_expectation().field_expectation(0);
  EXPECT_EQ("bb", bb_expectation.field_name());
  EXPECT_EQ(ValueExpectation::EQ,
            bb_expectation.value_expectation().operator_());
  EXPECT_EQ("2", bb_expectation.value_expectation().value());

  proto_.add_repeated_nested_message()->set_bb(1);
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.add_repeated_nested_message()->set_bb(2);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.add_repeated_nested_message()->set_bb(3);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
}

TEST_F(ExpectationConverterTest, RepeatedMessageHaveAtIndex) {
  CHECK(TextFormat::ParseFromString(
      "repeated_nested_message: { have: { bb: { eq: \"2\" }"
      "                                   at_index: { eq: \"1\" } } }",
      &expectation_));
  CHECK(Convert());
  EXPECT_EQ(1, generic_expectation_.field_expectation_size());
  const FieldExpectation& expectation =
      generic_expectation_.field_expectation(0);
  EXPECT_EQ("repeated_nested_message", expectation.field_name());
  EXPECT_EQ(1, expectation.repeated_message_expectation().have_size());
  const RepeatedMessageExpectation::Have& have =
      expectation.repeated_message_expectation().have(0);
  EXPECT_EQ(1, have.message_expectation().field_expectation_size());
  const FieldExpectation& bb_expectation =
      have.message_expectation().field_expectation(0);
  EXPECT_EQ("bb", bb_expectation.field_name());
  EXPECT_EQ(ValueExpectation::EQ,
            bb_expectation.value_expectation().operator_());
  EXPECT_EQ("2", bb_expectation.value_expectation().value());
  EXPECT_EQ(ValueExpectation::EQ, have.at_index().operator_());
  EXPECT_EQ("1", have.at_index().value());

  proto_.add_repeated_nested_message()->set_bb(2);
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.add_repeated_nested_message()->set_bb(2);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.add_repeated_nested_message()->set_bb(2);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
}

TEST_F(ExpectationConverterTest, RepeatedMessageDoNotHave) {
  CHECK(TextFormat::ParseFromString(
      "repeated_nested_message: { do_not_have: { bb: { eq: \"2\" } } }",
      &expectation_));
  CHECK(Convert());
  EXPECT_EQ(1, generic_expectation_.field_expectation_size());
  const FieldExpectation& expectation =
      generic_expectation_.field_expectation(0);
  EXPECT_EQ("repeated_nested_message", expectation.field_name());
  EXPECT_TRUE(expectation.has_repeated_message_expectation());
  EXPECT_EQ(1, expectation.repeated_message_expectation().do_not_have_size());
  const RepeatedMessageExpectation::DoNotHave& do_not_have =
      expectation.repeated_message_expectation().do_not_have(0);
  EXPECT_EQ(1,
            do_not_have.message_expectation().field_expectation_size());
  const FieldExpectation& bb_expectation =
      do_not_have.message_expectation().field_expectation(0);
  EXPECT_EQ("bb", bb_expectation.field_name());
  EXPECT_EQ(ValueExpectation::EQ,
            bb_expectation.value_expectation().operator_());
  EXPECT_EQ("2", bb_expectation.value_expectation().value());

  proto_.add_repeated_nested_message()->set_bb(1);
  EXPECT_TRUE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.add_repeated_nested_message()->set_bb(2);
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
  proto_.add_repeated_nested_message()->set_bb(3);
  EXPECT_FALSE(Evaluate(generic_expectation_, proto_, NULL));
}

}  // namespace protobuf_expectation
}  // namespace google
